package com.zhouwd.zcamera;

import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;

import java.util.concurrent.CopyOnWriteArrayList;

public class AudioRecordManager{

    private static final String TAG = AudioRecordManager.class.getSimpleName();

    // 音频获取源
    private static final int AUDIO_SOURCE = MediaRecorder.AudioSource.MIC;
    // 设置音频采样率，44100是目前的标准，但是某些设备仍然支持22050，16000，11025
    private static final int SAMPLE_RATE_IN_HZ = 44100;
    // 设置音频的录制的声道CHANNEL_IN_STEREO为双声道，CHANNEL_CONFIGURATION_MONO为单声道
    private static final int CHANNEL_CONFIG = AudioFormat.CHANNEL_IN_MONO;
    // 音频数据格式:PCM 16位每个样本。保证设备支持。PCM 8位每个样本。不一定能得到设备支持。
    private static final int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT;

    private boolean isRecord = false;// 设置正在录制的状态

    private boolean isRecordClose = false;//是否音频记录开关

    private AudioRecord audioRecord;//音频录制器


    /**
     * 数据回调监听器
     */
    public interface DataCallBack {
        void callBack(byte[] audiodata);
    }

    private DataCallBack dataCallBack;

    /**
     * 添加数据回调监听器
     * @param dataCallBack
     */
    public void addDataCallBack(DataCallBack dataCallBack) {
        this.dataCallBack = dataCallBack;
    }


    public AudioRecordManager() {

    }

    /**
     * 开始录制
     */
    public void startRecord() {

        if (audioRecord == null) {
            //录制缓冲大小
            // 声明recoordBufffer的大小字段
            int recordBufSize = AudioRecord.getMinBufferSize(SAMPLE_RATE_IN_HZ, CHANNEL_CONFIG, AUDIO_FORMAT);
            //音频录制
            audioRecord = new AudioRecord(AUDIO_SOURCE, SAMPLE_RATE_IN_HZ, CHANNEL_CONFIG, AUDIO_FORMAT, recordBufSize);
        }

        //开始录制
        audioRecord.startRecording();
        isRecord = true;
        // 开启音频文件写入线程
        new Thread(new AudioRecordThread()).start();
    }

    /**
     * 停止录制
     */
    public void stopRecord() {
        isRecord = false;//停止文件写入
        if (audioRecord != null) {
            //结束
            audioRecord.stop();
            audioRecord.release();//释放资源
            audioRecord = null;
        }
    }

    /**
     * 关闭
     */
    public void close() {
        if (audioRecord != null) {
            audioRecord.release();//释放资源
            audioRecord = null;
        }
    }
    /**
     * 这里将数据写入文件，但是并不能播放，因为AudioRecord获得的音频是原始的裸音频，
     * 如果需要播放就必须加入一些格式或者编码的头信息。但是这样的好处就是你可以对音频的 裸数据进行处理，比如你要做一个爱说话的TOM
     * 猫在这里就进行音频的处理，然后重新封装 所以说这样得到的音频比较容易做一些音频的处理。
     */
    class AudioRecordThread implements Runnable {
        @Override
        public void run() {
            // new一个byte数组用来存一些字节数据，大小为缓冲区大小
            // 缓冲区字节大小
            int bufferSizeInBytes = 320;
            byte[] audiodata = new byte[bufferSizeInBytes];
            int readsize;
            while (isRecord) {
                //每次读取指定大小
                readsize = audioRecord.read(audiodata, 0, bufferSizeInBytes);
                if (AudioRecord.ERROR_INVALID_OPERATION != readsize) {//判断大小
                    //Log.e(TAG, "writeDateTOFile: audiodata--->" + audiodata.length);
                    if (!isRecordClose) {
                        //广播回调
                        if (dataCallBack != null) {
                            dataCallBack.callBack(audiodata);
                        }
                    }
                }
            }
        }
    }

}
